package cc.rengu.igas.opms.core.service.trans.gateway;

import cc.rengu.igas.acct.facade.request.VirtAcctMultiMchntPreAuthCompRequest;
import cc.rengu.igas.acct.facade.request.VirtAcctPreAuthCancelRequest;
import cc.rengu.igas.momp.facade.base.Header;
import cc.rengu.igas.momp.facade.bean.CouponBriefInfoBean;
import cc.rengu.igas.momp.facade.bean.PaymentReturnOrderInfoBean;
import cc.rengu.igas.momp.facade.request.ComboPaymentRefundRequest;
import cc.rengu.igas.momp.facade.request.ReturnCouponRequest;
import cc.rengu.igas.opms.common.constant.OpmsParamConstant;
import cc.rengu.igas.opms.common.enums.RespCodeEnum;
import cc.rengu.igas.opms.facade.request.CpcnOrderRefundNoticeRequest;
import cc.rengu.igas.opms.facade.response.CpcnOrderRefundNoticeResponse;
import cc.rengu.igas.share.common.constant.ShareTreeNodeConstant;
import cc.rengu.igas.share.common.constant.TransCacheConstant;
import cc.rengu.oltp.service.base.BizBaseService;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.dao.MchntOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.PayOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.UserOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.impl.MchntOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.PayOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.UserOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.entity.MchntOrderInfo;
import cc.rengu.oltp.service.common.entity.PayOrderInfo;
import cc.rengu.oltp.service.common.entity.UserOrderInfo;
import cc.rengu.oltp.service.common.enums.*;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.model.RiskMonitorInfo;
import cc.rengu.oltp.service.realize.DubboService;
import cc.rengu.oltp.service.realize.OrderService;
import cc.rengu.oltp.service.realize.impl.DubboServiceImpl;
import cc.rengu.oltp.service.realize.impl.OrderServiceImpl;
import cc.rengu.oltp.utility.util.*;
import com.alibaba.fastjson.JSON;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 中金企业网关支付订单退款结果通知
 * T00PM062
 * 中金网关->open->支付通道->收银台
 *
 * @author fuyp
 * @date 2020/7/21.
 */
public class CpcnOrderRefundNoticeService extends BizBaseService {
    @Override
    protected Object beforeBizProcess() throws Exception {
        CpcnOrderRefundNoticeRequest cpcnOrderRefundNoticeRequest = new CpcnOrderRefundNoticeRequest();
        ConvertUtil.convertOutput(cpcnOrderRefundNoticeRequest);
        return cpcnOrderRefundNoticeRequest;
    }

    @Override
    protected BizResponse callBizService(Object request) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String instId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID);
        CpcnOrderRefundNoticeRequest cpcnOrderRefundNoticeRequest = (CpcnOrderRefundNoticeRequest) request;
        String refundTime = cpcnOrderRefundNoticeRequest.getRefundTime(); //退款时间
        String refundStatus = cpcnOrderRefundNoticeRequest.getRefundStatus(); //状态:20=退款失败(结算金额小于退款金额) 40=已经执行(已经发送转账指令)
        CpcnOrderRefundNoticeResponse cpcnOrderRefundNoticeResponse = new CpcnOrderRefundNoticeResponse();
        BizResponse response = new BizResponse();
        OrderService orderService = new OrderServiceImpl();

        /*根据??订单号查询退款订单表*/
        PayOrderInfoMapper payOrderInfoMapper = new PayOrderInfoMapperImpl();
        List<PayOrderInfo> payOrderInfoList = payOrderInfoMapper.selectPayOrderInfoByOrigSysSeqNum(cpcnOrderRefundNoticeRequest.getHeader().getInstId(), cpcnOrderRefundNoticeRequest.getSerialNumber());
        payOrderInfoList = payOrderInfoList.stream().filter(item -> item.getMsgDstId().equals(ChannelEnum.UPAC.getChannelType())).collect(Collectors.toList());
        if (payOrderInfoList.size() != 1) {
            rglog.error("机构<{}>没有对应的订单号流水<{}>信息", cpcnOrderRefundNoticeRequest.getHeader().getInstId(), cpcnOrderRefundNoticeRequest.getSerialNumber());
            throw new BizException("36", "与原交易信息不符");
        }

        /*判断原退款交易是否已经成功*/
        PayOrderInfo payOrderInfo = payOrderInfoList.get(0);
        if (TransStatusEnum.TRANS_SUCC.getStatus().equals(payOrderInfo.getTransStatus()) &&
                (BizStatusEnum.FINISH.getStatus().equals(payOrderInfo.getBizStatus()) ||
                        BizStatusEnum.REFUND.getStatus().equals(payOrderInfo.getBizStatus()) ||
                        BizStatusEnum.PART_REFUND.getStatus().equals(payOrderInfo.getBizStatus()) ||
                        BizStatusEnum.CONFIRM.getStatus().equals(payOrderInfo.getBizStatus()))) {
            rglog.error("订单已成功，不处理直接返回结果");
            cpcnOrderRefundNoticeResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
            cpcnOrderRefundNoticeResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
            response.setResult(cpcnOrderRefundNoticeResponse);
            response.setRspSysId(AppParamConstant.IGAS);
            response.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespCode());
            response.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
            return response;
        }

        /* 根据原交易流水号查询用户订单信息 */
        UserOrderInfoMapper userOrderInfoMapper = new UserOrderInfoMapperImpl();
        UserOrderInfo userRefundOrderInfo = userOrderInfoMapper.selectUserOrderInfoByPrimaryKey(cpcnOrderRefundNoticeRequest.getHeader().getInstId(), cpcnOrderRefundNoticeRequest.getSerialNumber());
        if (userRefundOrderInfo == null) {
            rglog.error("机构<{}>没有对应的原交易流水号<{}>退款订单信息", cpcnOrderRefundNoticeRequest.getHeader().getInstId(), cpcnOrderRefundNoticeRequest.getSerialNumber());
            throw new BizException("36", "与原交易信息不符");
        }
        /*获取退款的商户订单*/
        MchntOrderInfoMapper mchntOrderInfoMapper = new MchntOrderInfoMapperImpl();
        List<MchntOrderInfo> mchntRefundOrderInfoList = mchntOrderInfoMapper.selectMchntOrderInfoBySysSeqNum(userRefundOrderInfo.getInstId(), userRefundOrderInfo.getSysSeqNum());

        /*获取原支付订单*/
        UserOrderInfo userOrderInfo = userOrderInfoMapper.selectUserOrderInfoByPrimaryKey(instId, userRefundOrderInfo.getOrigSysSeqNum());
        if (null == userOrderInfo) {
            rglog.info("用户支付订单不存在");
            throw new BizException(RespCodeEnum.ORDER_REFUND_ERROR.getRespCode(), RespCodeEnum.ORDER_REFUND_ERROR.getRespDesc());
        }

        /*获取退款订单对应的原商户支付订单*/
        List<MchntOrderInfo> mchntOrderInfoListAll = mchntOrderInfoMapper.selectMchntOrderInfoBySysSeqNum(instId, userOrderInfo.getSysSeqNum());
        if (null == mchntOrderInfoListAll || mchntOrderInfoListAll.size() == 0) {
            rglog.info("商户订单信息表中无该笔商户支付订单,instId:<{}>,sysSeqNum:<{}>.", instId, userOrderInfo.getSysSeqNum());
            throw new BizException(RespCodeEnum.ORDER_REFUND_ERROR.getRespCode(), RespCodeEnum.ORDER_REFUND_ERROR.getRespDesc());
        }

        //计算当前退款的金额,以获取当前是部分退款还是全额退款
        String totalRefundAmt = "0.00";
        for (MchntOrderInfo mchntOrderInfo : mchntOrderInfoListAll) {
            /*累计用户退款金额*/
            if (mchntOrderInfo.getRefundAmt() != null) {
                totalRefundAmt = AmountUtil.addition(mchntOrderInfo.getRefundAmt(), totalRefundAmt);
            }
        }
        totalRefundAmt = AmountUtil.addition(userRefundOrderInfo.getOrderAmt(), totalRefundAmt);
        rglog.info("当前交易已退款金额:<{}>", totalRefundAmt);
        if (AmountUtil.compare(userOrderInfo.getOrderAmt(), totalRefundAmt) == 0) {
            /*用户全额退款*/
            xmlTreeUtil.setXmlTreeStringValue("refundType", AppParamConstant.YES);
            userOrderInfo.setBizStatus(BizStatusEnum.REFUND.getStatus());
        } else {
            xmlTreeUtil.setXmlTreeStringValue("refundType", AppParamConstant.NO);
            userOrderInfo.setBizStatus(BizStatusEnum.PART_REFUND.getStatus());
        }

        //计算原支付交易商户订单的退款金额
        List<MchntOrderInfo> mchntOrderInfoList = new ArrayList<>();
        for (MchntOrderInfo mchntOrderInfoRefund : mchntRefundOrderInfoList) {
            List<MchntOrderInfo> mchntOrderInfos = mchntOrderInfoListAll.stream().filter(item -> item.getMchntNo().equals(mchntOrderInfoRefund.getMchntNo())).collect(Collectors.toList());
            /*累计退款金额*/
            MchntOrderInfo mchntOrderInfo = mchntOrderInfos.get(0);
            mchntOrderInfo.setRefundAmt(AmountUtil.addition(mchntOrderInfo.getRefundAmt(), mchntOrderInfoRefund.getOrderAmt()));
            mchntOrderInfoList.add(mchntOrderInfo);
        }

        if ("40".equals(refundStatus)) {
            /*退款成功,更新当前退款订单状态*/
            userRefundOrderInfo.setTransStatus(TransStatusEnum.TRANS_SUCC.getStatus());
            userRefundOrderInfo.setBizStatus(BizStatusEnum.FINISH.getStatus());
            userRefundOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
            for (MchntOrderInfo mchntOrderInfo : mchntRefundOrderInfoList) {
                mchntOrderInfo.setTransStatus(TransStatusEnum.TRANS_SUCC.getStatus());
                mchntOrderInfo.setBizStatus(BizStatusEnum.FINISH.getStatus());
                mchntOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
            }
            payOrderInfo.setTransStatus(TransStatusEnum.TRANS_SUCC.getStatus());
            payOrderInfo.setBizStatus(BizStatusEnum.FINISH.getStatus());
            payOrderInfo.setSettleDate(refundTime.substring(0, 8));
            payOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));

            //更新原支付订单
            if (!orderService.updateOrderInfo(userOrderInfo, mchntOrderInfoList, null)) {
                rglog.error("更新原支付订单状态失败");
                throw new BizException(RespCodeEnum.UPDATE_ORDER_ERROR.getRespCode(), RespCodeEnum.UPDATE_ORDER_ERROR.getRespDesc());
            }

            //更新退款交易的订单状态
            if (!orderService.updateOrderInfo(userRefundOrderInfo, mchntRefundOrderInfoList, payOrderInfo)) {
                rglog.error("更新退款订单状态失败");
                throw new BizException(RespCodeEnum.UPDATE_ORDER_ERROR.getRespCode(), RespCodeEnum.UPDATE_ORDER_ERROR.getRespDesc());
            }

            /*异步调用预授权完成*/
            virtAcctPreAuthComp(userRefundOrderInfo, mchntRefundOrderInfoList);

            /*退款推送消息*/
            refundMsgPush(userRefundOrderInfo);

            /*判断是否参与营销，参与则调用营销退款*/
            List<MchntOrderInfo> mchntOrderInfoListMchnt = mchntOrderInfoList.stream().filter(item -> item.getMchntNo().equals(mchntRefundOrderInfoList.get(0).getMchntNo())).collect(Collectors.toList());
            if (mchntOrderInfoListMchnt.size() == 1) {
                MchntOrderInfo mchntOrderInfoPay = mchntOrderInfoListMchnt.get(0);
                if (mchntOrderInfoPay.getCustomerMarketAmt() != null && AmountUtil.compare(mchntOrderInfoPay.getCustomerMarketAmt(), "0.00") != 0) {
                    mompComboPayRefund(userOrderInfo, userRefundOrderInfo, mchntRefundOrderInfoList, payOrderInfoList, AcctTypeEnum.ALL.getAcctType());
                }
            }

            //购买卡券的交易进行卡券退回
            returnCouponFinish(mchntRefundOrderInfoList, payOrderInfoList, "1");

        } else if ("20".equals(refundStatus)) {
            /*更新订单表状态为失败*/
            userRefundOrderInfo.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
            userRefundOrderInfo.setBizStatus(BizStatusEnum.FINISH.getStatus());
            userRefundOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
            for (MchntOrderInfo mchntOrderInfo : mchntRefundOrderInfoList) {
                mchntOrderInfo.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
                mchntOrderInfo.setBizStatus(BizStatusEnum.FINISH.getStatus());
                mchntOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
            }
            payOrderInfo.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
            payOrderInfo.setBizStatus(BizStatusEnum.FINISH.getStatus());
            payOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
            if (!orderService.updateOrderInfo(userRefundOrderInfo, mchntRefundOrderInfoList, payOrderInfo)) {
                rglog.error("更新订单表状态失败");
            }

            /*明确失败调用预授权撤销*/
            virtAcctPreAuthCancel(payOrderInfoList, mchntRefundOrderInfoList.get(0));
        }

        ConvertUtil.convertOutput(cpcnOrderRefundNoticeResponse);
        response.setResult(cpcnOrderRefundNoticeResponse);
        response.setRspSysId(AppParamConstant.IGAS);
        response.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        response.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        return response;
    }

    @Override
    protected void afterBizProcess(BizResponse response) throws Exception {
        CpcnOrderRefundNoticeResponse cpcnOrderRefundNoticeResponse = (CpcnOrderRefundNoticeResponse) response.getResult();
        ConvertUtil.convertInput(cpcnOrderRefundNoticeResponse);
    }

    @Override
    protected RiskMonitorInfo getRiskMonitorInfo() {
        return null;
    }


    private PayOrderInfo convPayOrderInfo(UserOrderInfo userOrderInfo, String chanId, String destTxnNum) throws Exception {
        PayOrderInfo payOrderInfo = new PayOrderInfo();
        BeanUtil.beanCopy(userOrderInfo, payOrderInfo);
        if (payOrderInfo.getOrderAmt() == null || payOrderInfo.getOrderAmt().isEmpty()) {
            payOrderInfo.setOrderAmt("0.00");
        }
        payOrderInfo.setMsgDstId(chanId);
        payOrderInfo.setDstCallIndex("0");
        payOrderInfo.setChannelSeqNum(payOrderInfo.getSysSeqNum() + payOrderInfo.getDstCallIndex());
        payOrderInfo.setChannelReconKey(payOrderInfo.getSysSeqNum() + payOrderInfo.getDstCallIndex());
        payOrderInfo.setDstTxnNum(destTxnNum);
        payOrderInfo.setPayType(PayTypeEnum.CUPS_CLOUD.getPayType());
        payOrderInfo.setBizStatus(BizStatusEnum.PROCESSING.getStatus());
        payOrderInfo.setTransStatus(TransStatusEnum.TRANS_INIT.getStatus());
        payOrderInfo.setCreateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));

        return payOrderInfo;
    }

    /*预授权撤销*/
    void virtAcctPreAuthCancel(List<PayOrderInfo> payOrderInfoList, MchntOrderInfo mchntRefundOrderInfo) throws Exception {
        if ("00".equals(mchntRefundOrderInfo.getBizSceneType())) {
            return;
        }
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        DubboService dubboService = new DubboServiceImpl();
        List<PayOrderInfo> payOrderInfoListAcct = payOrderInfoList.stream().filter(item -> item.getMsgDstId().equals(ChannelEnum.ACCT.getChannelType())).sorted(Comparator.comparing(PayOrderInfo::getDstCallIndex)).collect(Collectors.toList());
        if (payOrderInfoListAcct == null || payOrderInfoListAcct.size() == 0) {
            return;
        }
        int iReturnCode = 0;
        VirtAcctPreAuthCancelRequest virtAcctPreAuthCancelRequest = new VirtAcctPreAuthCancelRequest();
        ConvertUtil.convertOutput(virtAcctPreAuthCancelRequest);
        cc.rengu.igas.acct.facade.base.Header header = virtAcctPreAuthCancelRequest.getHeader();
        header.setTxnNum("P06AT300");
        virtAcctPreAuthCancelRequest.setFreezeAcctSeqNum(payOrderInfoListAcct.get(0).getChannelSeqNum());
        virtAcctPreAuthCancelRequest.setUserType("00");
        virtAcctPreAuthCancelRequest.setUserId(mchntRefundOrderInfo.getMchntNo());
        virtAcctPreAuthCancelRequest.setTransAmt(payOrderInfoListAcct.get(0).getRealPayAmt());
        header.setTraceNo(sysSeqNum + "0");
        virtAcctPreAuthCancelRequest.setHeader(header);
        iReturnCode = dubboService.asynCallDubboService("virtAcctService", "virtAcctPreAuthCancel", virtAcctPreAuthCancelRequest, "AsynVirtAcctPreAuthCancelService");
        if (iReturnCode != 0) {
            rglog.error("异步虚拟账户预授权撤销服务注册失败！");
        }
    }


    /**
     * 卡券退回完成-异步调用
     *
     * @param refundMchntOrderInfoList - 卡券退款订单
     * @throws Exception 异常
     */
    void returnCouponFinish(List<MchntOrderInfo> refundMchntOrderInfoList, List<PayOrderInfo> payOrderInfoList, String couponLockFlag) {

        if (!"00".equals(refundMchntOrderInfoList.get(0).getBizSceneType())) {
            /*非卡券购买退单，直接返回*/
            return;
        }

        try {
            List<PayOrderInfo> payOrderInfoMomp = payOrderInfoList.stream().filter(item -> item.getMsgDstId().equals(ChannelEnum.MOMP.getChannelType())).collect(Collectors.toList());

            Header header = new Header();
            header.setChanlId(OpmsParamConstant.OPM_SYS_ID);
            header.setSrcSysId(AppParamConstant.SYS_ID);
            header.setBizType("00");
            header.setTxnNum("P04MO002");
            header.setVersion("1.0.0");
            header.setTraceNo(payOrderInfoMomp.get(0).getChannelReconKey());
            header.setTransTime(DateUtil.getCurrentTime());
            header.setTransDate(DateUtil.getCurrentDate());

            List<CouponBriefInfoBean> couponBriefInfoBeanList = new ArrayList<>();
            for (MchntOrderInfo mchntOrderInfo : refundMchntOrderInfoList) {
                CouponBriefInfoBean couponBriefInfoBean = new CouponBriefInfoBean();
                couponBriefInfoBean.setCouponNo(mchntOrderInfo.getMchntNo());
                couponBriefInfoBean.setCouponLockFlag(couponLockFlag);
                couponBriefInfoBeanList.add(couponBriefInfoBean);
            }
            ReturnCouponRequest returnCouponRequest = new ReturnCouponRequest();
            returnCouponRequest.setHeader(header);
            returnCouponRequest.setCouponInfoList(couponBriefInfoBeanList);
            DubboService dubboService = new DubboServiceImpl();
            int iReturnCode = dubboService.asynCallDubboService(OpmsParamConstant.DUBBO_MOMP_COUPON_MANAGEMENT_SERVICE, "returnCoupon", returnCouponRequest, "AsynReturnCouponService");
            if (iReturnCode != 0) {
                rglog.error("异步卡券退回完成服务注册失败！");
            }
        } catch (Exception e) {
            rglog.error(e.getMessage());
            rglog.error("异步营销退款失败！");
        }

    }

    /**
     * 预授权完成
     *
     * @param refundOrderInfo          退款用户订单
     * @param mchntRefundOrderInfoList 退款商户订单
     */
    void virtAcctPreAuthComp(UserOrderInfo refundOrderInfo, List<MchntOrderInfo> mchntRefundOrderInfoList) {
        if ("00".equals(mchntRefundOrderInfoList.get(0).getBizSceneType()) ||
                "01".equals(mchntRefundOrderInfoList.get(0).getBizSceneType()) ||
                "02".equals(mchntRefundOrderInfoList.get(0).getBizSceneType()) ||
                "0".equals(mchntRefundOrderInfoList.get(0).getFeeInputMode())) {
            return;
        }

        try {
            VirtAcctMultiMchntPreAuthCompRequest virtAcctPreAuthCompRequest = new VirtAcctMultiMchntPreAuthCompRequest();
            cc.rengu.igas.acct.facade.base.Header header = new cc.rengu.igas.acct.facade.base.Header();
            header.setInstId(refundOrderInfo.getInstId());
            header.setChanlId(OpmsParamConstant.OPM_SYS_ID);
            header.setSrcSysId(AppParamConstant.SYS_ID);
            header.setBizType("00");
            header.setVersion("1.0.0");
            header.setTransTime(DateUtil.getCurrentTime());
            header.setTransDate(DateUtil.getCurrentDate());
            header.setTxnNum("P06AT501");
            header.setTraceNo(refundOrderInfo.getSysSeqNum() + "1");
            virtAcctPreAuthCompRequest.setTransSeqNum(refundOrderInfo.getSysSeqNum());
            virtAcctPreAuthCompRequest.setAcctType("00");
            virtAcctPreAuthCompRequest.setHeader(header);

            PayOrderInfo payOrderInfoAcctComp = convPayOrderInfo(refundOrderInfo, ChannelEnum.ACCT.getChannelType(), "P06AT501");
            OrderService orderService = new OrderServiceImpl();
            if (!orderService.registerOrderInfo(null, null, payOrderInfoAcctComp)) {
                rglog.error("登记支付订单表失败,payOrderInfo=[{}]", JSON.toJSONString(payOrderInfoAcctComp));
            }

            DubboService dubboService = new DubboServiceImpl();
            int iReturnCode = dubboService.asynCallDubboService(OpmsParamConstant.DUBBO_ACCT_VIRTACCT_SERVICE, "virtAcctMultiMchntPreAuthComp", virtAcctPreAuthCompRequest, "AsynVirtAcctPreAuthCompService");
            if (iReturnCode != 0) {
                rglog.error("异步虚拟账户预授权完成服务注册失败！");
            }
        } catch (Exception e) {
            rglog.error(e.getMessage());
        }
    }

    /**
     * 营销优惠退款-异步调用
     *
     * @param userOrderInfo            用户订单
     * @param mchntRefundOrderInfoList 商户订单
     * @throws Exception 异常
     */
    void mompComboPayRefund(UserOrderInfo userOrderInfo, UserOrderInfo refundOrderInfo, List<MchntOrderInfo> mchntRefundOrderInfoList, List<PayOrderInfo> payOrderInfoList, String acctType) {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        DubboService dubboService = new DubboServiceImpl();
        try {
            String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
            /*调用营销接口进行优惠试算*/
            Header header = new Header();
            header.setInstId(userOrderInfo.getInstId());
            header.setChanlId(OpmsParamConstant.OPM_SYS_ID);
            header.setSrcSysId(AppParamConstant.SYS_ID);
            header.setBizType("00");
            header.setTxnNum("P04MO002");
            header.setVersion("1.0.0");
            header.setTraceNo(sysSeqNum + "1");
            header.setTransTime(DateUtil.getCurrentTime());
            header.setTransDate(DateUtil.getCurrentDate());
            ComboPaymentRefundRequest comboPaymentReturnRequest = new ComboPaymentRefundRequest();
            ConvertUtil.convertOutput(comboPaymentReturnRequest);
            comboPaymentReturnRequest.setHeader(header);
            comboPaymentReturnRequest.setUserId(userOrderInfo.getUserId());
            comboPaymentReturnRequest.setMchntOrderId(userOrderInfo.getMchntOrderId());
            comboPaymentReturnRequest.setTransAmt(userOrderInfo.getOrderAmt());
            comboPaymentReturnRequest.setReturnAmt(refundOrderInfo.getOrderAmt());
            List<PaymentReturnOrderInfoBean> orderDetailList = new ArrayList<>();
            convertOrderDetail(orderDetailList, mchntRefundOrderInfoList);
            comboPaymentReturnRequest.setReturnOrderDetailList(orderDetailList);
            int iReturnCode = dubboService.asynCallDubboService("paymentService", "comboPaymentReturn", comboPaymentReturnRequest, "AsynComboPaymentReturnService");
            if (iReturnCode != 0) {
                rglog.error("异步虚拟账户预授权完成服务注册失败！");
            }
        } catch (Exception e) {
            rglog.error(e.getMessage());
            rglog.error("异步营销退款失败！");
        }

    }

    void convertOrderDetail(List<PaymentReturnOrderInfoBean> orderDetailList, List<MchntOrderInfo> mchntOrderInfoList) {
        for (MchntOrderInfo mchntOrderInfo : mchntOrderInfoList) {
            PaymentReturnOrderInfoBean paymentOrderDetailBean = new PaymentReturnOrderInfoBean();
            paymentOrderDetailBean.setMchntNo(mchntOrderInfo.getMchntNo());
            orderDetailList.add(paymentOrderDetailBean);
        }
    }

    /**
     * 退款消息推送
     *
     * @param refundOrderInfo 退款的用户订单
     */
    void refundMsgPush(UserOrderInfo refundOrderInfo) {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        try {
            GlobalTransUtil.setCacheValue(TransCacheConstant.USER_ORDER_INFO, refundOrderInfo);
            int iReturnCode = asynnotify.transactionNotice("MchntTransNoticeService", 1, 0, 0);
            if (0 != iReturnCode) {
                rglog.error("提交交易结果异步通知给商户失败!");
            }
        } catch (Exception e) {
            rglog.error(e.getMessage());
        }
    }

}
